package com.travel.api;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayUtil;
import com.travel.dto.WxPayDTO;
import com.travel.utils.SignUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chendikai
 * @date 2024-07-23 10:12
 */
@RestController
@RequestMapping("/api/wxpay")
@Api(tags = "微信支付接口")
public class WeChatPayController {
    @Autowired
    private WXPayConfig wxPayConfig;
    @Value("${pay-platform.wx.pay.appId}")
    private String appId;
    @Value("${pay-platform.wx.pay.secret}")
    private String secret;

    @ApiOperation(value = "创建微信支付订单，获取预支付交易会话标识")
    @ApiImplicitParam(name = "wxPayDTO", required = true, value = "订单号，订单金额，用户openid")
    @PostMapping("/createOrder")
    public Map<String, String> createOrder(@RequestBody WxPayDTO wxPayDTO, HttpServletRequest request) {
        try {
            WXPay wxPay = new WXPay(wxPayConfig);

            Map<String, String> data = new HashMap<>();
            data.put("body", "Product description");
            data.put("out_trade_no", wxPayDTO.getOrderNo());
            data.put("total_fee", wxPayDTO.getAmount()); // 单位为分
            data.put("spbill_create_ip", request.getRemoteAddr());
            data.put("notify_url", "https://huaqing.xgxtravel.com/api/wxpay/notify");
            data.put("trade_type", "JSAPI"); // 此处的trade_type可根据具体的业务场景进行调整
            data.put("openid", wxPayDTO.getOpenid()); // 此处的trade_type可根据具体的业务场景进行调整

            Map<String, String> response = wxPay.unifiedOrder(data);
            //时间戳
            long timestamp = System.currentTimeMillis() / 1000;
            Map<String, String> datas = new HashMap<>();
            datas.put("appId", appId);
            datas.put("timeStamp", String.valueOf(timestamp));
            datas.put("nonceStr", response.get("nonce_str"));
            datas.put("package", "prepay_id=" + response.get("prepay_id"));
            datas.put("signType", "MD5");

            String paySign = SignUtils.generatePaySign(datas, "xinganxian8888888888888888888888");

            // String sign = Sign.getToken(appId, response.get("prepay_id"), response.get("nonce_str"), timestamp);
            response.put("sign", paySign);
            response.put("timestamp", String.valueOf(timestamp));
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    @ApiIgnore
    @PostMapping("/notify")
    public String payNotify(@RequestBody String xmlData) {
        // 处理支付回调
        // 验证签名，处理业务逻辑等
        try {
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xmlData); // 将微信的回调信息解析成Map
            WXPay wxPay = new WXPay(wxPayConfig);

            if (wxPay.isPayResultNotifySignatureValid(notifyMap)) { // 验证签名
                // 签名验证成功后处理具体的业务逻辑
                // 比如更新订单状态等
                String returnCode = notifyMap.get("return_code");
                if ("SUCCESS".equals(returnCode)) {
                    // 处理业务逻辑
                    return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                } else {
                    return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理业务逻辑失败]]></return_msg></xml>";
                }
            } else {
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[异常错误]]></return_msg></xml>";
        }

    }
}
